from datetime import date
import logging

from django.core.paginator import Paginator
from django.http.response import JsonResponse
from django.shortcuts import render
from django.views import View

from apps.contents.utils import get_categories
from apps.goods.models import SKU, CategoryVisitCount, GoodsCategory
from utils.response_code import RETCODE

from .utils import get_breadcrumb

# Create your views here.

logger = logging.getLogger(__name__)


class GoodsCategoryListView(View):
    """商品分类展示列表"""

    def get(self, request, category_id, page_num):
        """展示商品分类列表"""
        # 获取分类信息
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except Exception as exc:
            logger.error(exc)
            return render(request, 'list.html', context={'errmsg': '没有此分类'})

        # 获取面包屑
        from .utils import get_breadcrumb
        breadcrumb = get_breadcrumb(category)

        # 获取排序方式，如果未获取到接设置为default
        sort = request.GET.get('sort', 'default')
        if sort == 'default':
            sort_filed = 'create_time'
        elif sort == 'price':
            sort_filed = 'price'
        else:
            sort_filed = 'sales'
        # 根据分类ID过滤出上架的商品并排序
        skus = SKU.objects.filter(
            category_id=category_id, is_launched=True).order_by(sort_filed)

        # 防止用户提交不合法的页数
        try:
            page_num = int(page_num)
        except Exception:
            page_num = 1

        try:
            # 创建分页器实例
            paginator = Paginator(skus, per_page=5)
            # 获取分页后的数据
            page_skus = paginator.page(page_num)
            # 获取总页数
            total_page = paginator.num_pages
        except Exception as exc:
            logger(exc)

 # 渲染页面
        context = {
            'categories': category,   # 频道分类
            'breadcrumb': breadcrumb,   # 面包屑导航
            'sort': sort,               # 排序字段
            'category': category,       # 第三级分类
            'page_skus': page_skus,     # 分页后数据
            'total_page': total_page,   # 总页数
            'page_num': page_num,       # 当前页码
        }

        return render(request, 'list.html', context=context)


class HotView(View):
    """热销商品展示"""

    def get(self, request, category_id):
        # 获取分类
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return JsonResponse({'code': RETCODE.NODATAERR, 'errmsg': '未查询到该分类信息'})

        # 获取该分类的热销商品
        skus = SKU.objects.filter(category=category, is_launched=True).order_by(
            '-sales')[:2]  # 默认是升序，改为降序并切片

        # 序列化
        hot_skus = []
        for sku in skus:
            hot_skus.append({
                'id': sku.id,
                'default_image_url': sku.default_image.url,
                'name': sku.name,
                'price': sku.price
            })

        return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_sku': hot_skus})


class DetailView(View):
    """商品详情"""

    def get(self, request, sku_id):
        """展示商品详情页"""
        try:
            # 获取当前SKU的信息
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return render(request, '404html')

        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        # 构建当前商品的规格键
        sku_specs = sku.specs.order_by('spec_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        # 获取当前商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            # 复制当前sku的规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options

        # 渲染页面
        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'specs': goods_specs,
        }
        return render(request, 'detail.html', context)


class CategoryVisitCountView(View):
    """统计商品分类访问量"""

    def get(self, request, category_id):
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return render(request, '404.html')

        # 获取当天日期
        from django.utils import timezone
        today = timezone.localdate()

        try:
            # 尝试获取该分类的访问量记录
            category_visit_count = CategoryVisitCount.objects.get(date=today,
                category_id=category_id)
        except CategoryVisitCount.DoesNotExist:
            # 没有获取到，就创建新的纪录
            CategoryVisitCount.objects.create(
                category_id=category_id,
                date=today,
                count=1
            )
        else:
            # 已有记录就更新记录
            category_visit_count.count += 1
            category_visit_count.save()

        return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})
